package br.com.cicero.notasfiscais.dao;

import java.io.Serializable;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

import br.com.cicero.notasfiscais.mb.QuantidadePorProduto;
import br.com.cicero.notasfiscais.modelo.NotaFiscal;
import br.com.cicero.notasfiscais.modelo.Produto;

public class DAO<T> implements Serializable {
	
	private final Class<T> classe;
	
	@Inject
	private final EntityManager em;
	
	public DAO(Class<T> classe, EntityManager em) {
		this.classe = classe;
		this.em = em;
	}
	
	public void adiciona(T t) {
		em.persist(t);
	}
	
	public void remove(T t) {
		em.remove(em.merge(t));
	}
	
	public void atualiza(T t) {
		em.merge(t);
	}
	
	public List<T> listaTodos() {
		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
		query.select(query.from(classe));
		List<T> lista = em.createQuery(query).getResultList();
			
		return lista;
	}
	
	public T buscaPorId(Long id) {
		return (T) em.find(classe, id);
	}

	public List<T> listaTodosPaginada(int inicio, int quantidade) {
		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
		query.select(query.from(classe));
		List<T> lista = em.createQuery(query).setFirstResult(inicio)
				.setMaxResults(quantidade).getResultList();
				
		return lista;
	}

	public int contaTodos() {
		 Query query = em.createQuery("select count(n) from " + classe.getName() + " n");
         Number result = (Number) query.getSingleResult();
                  
         return result.intValue();
	}
	
	@SuppressWarnings("unchecked")
	public List<QuantidadePorProduto> relatorioQuantidadePorProduto() {
		return em.createQuery(
				"select new br.com.cicero.notasfiscais.mb.QuantidadePorProduto(sum(i.quantidade), i.produto) "
				+ " from Item i group by i.produto").getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Produto> buscaPorNome(String nome) {
		String jpql = "select p from Produto p where lower(p.nome) like :nome order by p.nome";
		return em.createQuery(jpql).setParameter("nome", nome+"%").getResultList();
	}
			
}
